package com.sunwayworld.basemodule.business.result.scheduletask.service.impl;

import com.sunwayworld.basemodule.business.result.bean.LimsResultBean;
import com.sunwayworld.basemodule.business.result.computing.OrderTaskResultComputingEngine;
import com.sunwayworld.basemodule.business.result.scheduletask.dto.CsvRecordDTO;
import com.sunwayworld.basemodule.business.result.scheduletask.dto.ResultDTO;
import com.sunwayworld.basemodule.business.result.scheduletask.dto.SampleDTO;
import com.sunwayworld.basemodule.business.result.scheduletask.service.LimsResultAutoImportService;
import com.sunwayworld.basemodule.business.result.service.LimsResultService;
import com.sunwayworld.framework.executor.ExecutorHelper;
import com.sunwayworld.framework.mybatis.mapper.MatchPattern;
import com.sunwayworld.framework.mybatis.mapper.SearchFilter;
import com.sunwayworld.framework.spring.annotation.GikamBean;
import com.sunwayworld.framework.utils.CollectionUtils;
import com.sunwayworld.framework.utils.FtpUtils;
import com.sunwayworld.framework.utils.StringUtils;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import org.apache.commons.io.input.BOMInputStream;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @ClassName LimsI18NAutoTranslateServiceImpl
 * @Author zhoujq
 * @Date 2023/7/5
 * @Version 1.0
 **/
@Repository
@GikamBean
public class LimsResultAutoImportServiceImpl implements LimsResultAutoImportService {

    @Value("${hpvFtp.output}")
    private String oriPath;// 原文件地址

    @Value("${hpvFtp.readed}")
    private String readedPath;// 已读文件地址

    @Value("${hpvFtp.url1}")
    private String url1;// windows电脑1，ip
    @Value("${hpvFtp.port1}")
    private String port1;// windows电脑1，port

    @Value("${hpvFtp.url2}")
    private String url2;// windows电脑2，ip
    @Value("${hpvFtp.port2}")
    private String port2;// windows电脑2，port

    @Value("${hpvFtp.url3}")
    private String url3;// windows电脑3，ip
    @Value("${hpvFtp.port3}")
    private String port3;// windows电脑3，port

    @Value("${hpvFtp.url4}")
    private String url4;// windows电脑4，ip
    @Value("${hpvFtp.port4}")
    private String port4;// windows电脑4，port

    @Value("${hpvFtp.url5}")
    private String url5;// windows电脑5，ip
    @Value("${hpvFtp.port5}")
    private String port5;// windows电脑5，port

    @Value("${tbnkFtp.url}")
    private String tbnkUrl;// tbnk电脑
    @Value("${tbnkFtp.port}")
    private String tbnkPort;// tbnk电脑，port
    @Value("${tbnkFtp.output}")
    private String tbnkOutput;// tbnk未读目录
    @Value("${tbnkFtp.readed}")
    private String tbnkReaded;// tbnk已读目录

    @Value("${tbnkPdfFtp.url}")
    private String tbnkPdfUrl;// tbnk-pdf电脑
    @Value("${tbnkPdfFtp.port}")
    private String tbnkPdfPort;// tbnk-pdf电脑，port
    @Value("${tbnkPdfFtp.output}")
    private String tbnkPdfOutput;// tbnk-pdf未读目录
    @Value("${tbnkPdfFtp.readed}")
    private String tbnkPdfReaded;// tbnk-pdf已读目录


    public static final String ANYUSER = "anonymous";// ftp匿名登录用户名，密码为空

    public static final String HPVNAME = "透景hpv27项检测";// 用于匹配lims待录入结果的分析项的数据，检测项目名称：hpv项目
    public static final String HPVNCODE = "P00010";
    public static final String TBNKCSVNAME = "TBNK细胞免疫力检测-专项";// 用于匹配lims待录入结果的分析项的数据，检测项目名称：tbnk-CSV项目:P00030
    public static final String TBNKPDFNAME = "TBNK";// 用于匹配lims待录入结果的分析项的数据，检测项目名称：tbnk-PDF项目:P00018，改为读取CSV文件
    // tbnk的一个csv(11项)，匹配lims产品编码：P00030，tbnk-pdf的6项，检测编码：P00018
    public static final String TBNKCSV = "P00030";
    public static final String TBNKPDF = "P00018";

    private static final Logger LOGGER = LoggerFactory.getLogger(LimsResultAutoImportServiceImpl.class);

    @Autowired
    private LimsResultService resultService;

    /*
    * 自动读取位于windows共享出的ftp远程文件服务，共五台电脑，分别获取文件并读取
    * 仅同步分析项的原始结果和最终结果均为空的数据，若有结果，则不覆盖现有结果
    * */
    @Override
    public void autoImport() {
        // 先获取哪些实验批次处于结果录入阶段
        List<LimsResultBean> oriResults = resultService.selectListByFilter(SearchFilter.instance()
            .match("RUNSTATUS", "logged").filter(MatchPattern.SEQ)// 实验批次处于结果录入
            .match("OTSTATUS", "logged").filter(MatchPattern.SB)// 工序任务处于结果录入
            .match("OTFALG", "1").filter(MatchPattern.SEQ));// 工序任务的标记为1;
        // 每台电脑都调取文件操作
        // 结果收集
        List<ResultDTO> results = new ArrayList<>();
        readHpvFiles(url1, port1, results);
        // readHpvFiles(url2, port2, results);
        // readHpvFiles(url3, port3, results);
        // readHpvFiles(url4, port4, results);
        // readHpvFiles(url5, port5, results);
        // 读取tbnk结果文件
        readTbnkFiles(tbnkUrl, tbnkPort, results);
        // 读取tbnk-pdf的结果文件，同一台电脑，文件格式改为读csv，同tbnk（11项），当前为csv-6项
        readTbnkFilesSix(tbnkPdfUrl, tbnkPdfPort, results);
        // readTbnkPdfFiles(tbnkPdfUrl, tbnkPdfPort, results);
        // 读取的所有结果
        if (CollectionUtils.isEmpty(results)) {
            return;
        }
        for (ResultDTO resultDTO : results) {
            LOGGER.info("读取数据：分院样本编号：{}， 分析项名：{}， 分析项值：{}， 检测项目：{}",
                resultDTO.getHissampleCode(), resultDTO.getAnalyte(), resultDTO.getResult(), resultDTO.getProductName());
        }
        // 更新结果到lims
        List<LimsResultBean> updateResults = new ArrayList<>();
        // 匹配并导入结果，按分析项对应的工序任务的检测项目名称，及分析项名称，及分院样本编号
        for (LimsResultBean oriResult: oriResults) {
            if (!StringUtils.isEmpty(oriResult.getExt$Item("PRODUCTCODE"))
                    && !StringUtils.isEmpty(oriResult.getExt$Item("HISSAMPLECODE"))
                    && !StringUtils.isEmpty(oriResult.getAnalyte())) {
                // 按检测编码指定匹配
                Optional<ResultDTO> resultOp = results.stream().filter(t->
                    oriResult.getExt$Item("PRODUCTCODE").contains(t.getProductCode())
                    && StringUtils.equalsIgnoreCase(t.getAnalyte(), oriResult.getAnalyte())
                    && StringUtils.equalsIgnoreCase(t.getHissampleCode(), oriResult.getExt$Item("HISSAMPLECODE"))
                ).findFirst();
                if (resultOp.isPresent()) {
                    oriResult.setOriginalResult(resultOp.get().getResult());
                    oriResult.setFinalResult(resultOp.get().getResult());
                    updateResults.add(oriResult);
                }
            }
        }
        if (CollectionUtils.isEmpty(updateResults)) {
            return;
        }
        resultService.getDao().fastUpdate(updateResults, "ORIGINALRESULT", "FINALRESULT");
        // 计算公式
        List<Long> folderIdList = updateResults.stream().map(LimsResultBean::getFolderId).distinct().collect(Collectors.toList());
        OrderTaskResultComputingEngine.getEngine(folderIdList).compute();
        ExecutorHelper.submit(() -> OrderTaskResultComputingEngine.getEngine(folderIdList).compute());
    }

    /*
    * 读取当前电脑的取hpv文件，收集结果，并将原文件移至已读文件
    * */
    public void readHpvFiles(String ip, String port, List<ResultDTO> results) {
        if (StringUtils.isEmpty(ip) || StringUtils.isEmpty(port)
            || StringUtils.isEmpty(oriPath) || StringUtils.isEmpty(readedPath)) {
            return;
        }
        // 匿名登录获取ftp连接
        FTPClient ftpClient = null;
        CSVParser parser = null;
        InputStream in = null;
        InputStreamReader is = null;
        BufferedReader br = null;
        try {
            ftpClient = FtpUtils.getFtpClient(ip, Integer.valueOf(port), ANYUSER, "");
            if (ftpClient == null) {
                return;
            }
            // 切换到未读文件夹
            ftpClient.changeWorkingDirectory(oriPath);
            FTPFile[] files = ftpClient.listFiles();
            if (files == null || files.length == 0) {
                LOGGER.info("HPV未读文件夹：{}下暂无文件", oriPath);
                return;
            }
            // 遍历文件夹，DataType:Median部分的数据，直至下一行的首列为DataType:结束
            for (FTPFile file: files) {
                // 如果不是文件，则跳过
                if (!file.isFile() || (!file.getName().endsWith("csv") && !file.getName().endsWith("CSV"))) {
                    continue;
                }
                LOGGER.info("读取HPV文件：{}", file.getName());
                // 直接从路径读取csv文件
                in = ftpClient.retrieveFileStream(dealChinesePath(oriPath + "/" + file.getName()));
                is = new InputStreamReader(in, "UTF-8");
                br = new BufferedReader(is);
                ftpClient.getReply();
                parser = new CSVParser(br, CSVFormat.DEFAULT);
                // 行数
                int index = 0;
                // 有效数据的标题行
                int titleIndex = 0;
                // 数据截止
                int endIndex = 0;
                // 当前数据分析项名
                List<String> analytes = new ArrayList<>();
                // 遍历CSV文件的每一行并获取单元格数据
                for (CSVRecord record : parser) {
                    index++;
                    // 第一列的值为：DataType:，且第二列的值为：Median
                    // 则下一列的标题，下下列为结果数据，直至遇到下一个DataType:截止
                    if (record.size() >= 2
                            && StringUtils.equalsIgnoreCase(record.get(0), "DataType:")
                            && StringUtils.equalsIgnoreCase(record.get(1), "Median")) {
                        titleIndex = index + 1;
                    }
                    // 标题行
                    if (index == titleIndex) {
                        for (int i = 0; i < record.size(); i++) {
                            if (i>1) {
                                // 第三列开始为分析项名
                                analytes.add(record.get(i));
                            }
                        }
                    }
                    if (record.size() >= 2
                            && StringUtils.equalsIgnoreCase(record.get(0), "DataType:")
                            && !StringUtils.equalsIgnoreCase(record.get(1), "Median")) {
                        endIndex = index;
                        // 在标题行的下一次遇到即退出
                        break;
                    }
                }
                // 重置迭代器
                in = ftpClient.retrieveFileStream(dealChinesePath(oriPath + "/" + file.getName()));
                is = new InputStreamReader(in, "UTF-8");
                br = new BufferedReader(is);
                ftpClient.getReply();
                parser = new CSVParser(br, CSVFormat.DEFAULT);
                // 从标题行下一行
                index = 0;
                if (titleIndex > 0 && endIndex > titleIndex) {
                    // 再次遍历获取指定区域的数据
                    for (CSVRecord record : parser) {
                        index++;
                        // 有效数据区域
                        if (index > titleIndex && index < endIndex) {
                            // 第二列hissampleCode非空才算有效数据
                            for (int i = 2; i < record.size(); i++) {
                                if (!StringUtils.isEmpty(record.get(1))
                                    && !StringUtils.isEmpty(record.get(2))) {
                                    ResultDTO resultDTO = new ResultDTO();
                                    resultDTO.setProductCode(HPVNCODE);
                                    resultDTO.setProductName(HPVNAME);
                                    resultDTO.setHissampleCode(record.get(1));
                                    resultDTO.setAnalyte(analytes.get(i-2));
                                    resultDTO.setResult(record.get(i));
                                    results.add(resultDTO);
                                }
                            }
                        }
                        if (index > endIndex) {
                            break;
                        }
                    }
                }
                index = 0;
                titleIndex = 0;
                endIndex = 0;
                in.close();
                is.close();
                br.close();
                parser.close();
            }
            for (FTPFile file: files) {
                // 如果不是文件，则跳过
                if (!file.isFile() || (!file.getName().endsWith("csv") && !file.getName().endsWith("CSV"))) {
                    continue;
                }
                ftpClient.rename(dealChinesePath(oriPath + "/" + file.getName()), dealChinesePath(readedPath + "/" + file.getName()));
            }
        } catch (Exception e) {
            LOGGER.error("读取HPV文件异常");
            e.printStackTrace();
        } finally {
            try {
                if (ftpClient != null) {
                    ftpClient.disconnect();
                }
                if (parser != null) {
                    // 关闭流
                    parser.close();
                }
                if (in != null) {
                    in.close();
                }
                if (is != null) {
                    is.close();
                }
                if (br != null) {
                    br.close();
                }
            } catch (Exception e) {
                LOGGER.error("关闭HPV文件流异常");
                e.printStackTrace();
            }
        }
    }

    /*
     * 读取当前电脑的取Tbnk文件，收集结果，并将原文件移至已读文件
     * */
    public void readTbnkFiles(String ip, String port, List<ResultDTO> results) {
        if (StringUtils.isEmpty(ip) || StringUtils.isEmpty(port)
            || StringUtils.isEmpty(tbnkOutput) || StringUtils.isEmpty(tbnkReaded)) {
            return;
        }
        // 匿名登录获取ftp连接
        FTPClient ftpClient = null;
        CSVParser parser = null;
        OutputStream os = null;
        InputStream in = null;
        InputStreamReader is = null;
        BufferedReader br = null;
        try {
            ftpClient = FtpUtils.getFtpClient(ip, Integer.valueOf(port), ANYUSER, "");
            if (ftpClient == null) {
                return;
            }
            // 文件层级为：/Output/20240417-TBNK_20240418_14_58 48_CSV/标本1_CSV/1.csv
            // 切换到未读文件夹
            ftpClient.changeWorkingDirectory(tbnkOutput);
            FTPFile[] files = ftpClient.listDirectories();
            if (files == null || files.length == 0) {
                LOGGER.info("TBNK未读文件夹：{}下暂无文件", tbnkOutput);
                return;
            }
            for (FTPFile file: files) {
                LOGGER.info("读取2级文件夹：{}", file.getName());
                // 进入二级
                ftpClient.changeWorkingDirectory(dealChinesePath(tbnkOutput + "/" + file.getName()));
                FTPFile[] files2 = ftpClient.listDirectories();
                for (FTPFile file2: files2) {
                    LOGGER.info("读取3级文件夹：{}", file2.getName());
                    // 进入三级
                    ftpClient.changeWorkingDirectory(dealChinesePath(tbnkOutput + "/" + file.getName() + "/" + file2.getName()));
                    FTPFile[] files3 = ftpClient.listFiles();
                    for (FTPFile file3: files3) {
                        // 如果不是文件，则跳过
                        if (!file3.isFile() || (!file3.getName().endsWith("csv") && !file3.getName().endsWith("CSV"))) {
                            continue;
                        }
                        LOGGER.info("读取TBNK文件：{}", file3.getName());
                        // 直接从路径读取csv文件
                        in = new BOMInputStream(ftpClient.retrieveFileStream(dealChinesePath(tbnkOutput + "/" + file.getName()+ "/" + file2.getName() + "/" + file3.getName())));
                        is = new InputStreamReader(in);
                        br = new BufferedReader(is);
                        parser = new CSVParser(br, CSVFormat.DEFAULT);
                        ftpClient.getReply();
                        // 获取每个样本的数据收集区域信息
                        List<SampleDTO> sampleDTOs = new ArrayList<>();
                        // 所有全称，即分析项的抬头
                        List<Integer> analyteTitileIndexs = new ArrayList<>();
                        // 所有第一个单元格非空的数据，有效数据
                        List<CsvRecordDTO> recordDTOS = new ArrayList<>();
                        int index = 0;
                        for (CSVRecord record : parser) {
                            index++;
                            if (!StringUtils.isEmpty(record.get(0))) {
                                CsvRecordDTO recordDTO = new CsvRecordDTO();
                                recordDTO.setIndex(index);
                                recordDTO.setFielde0(record.get(0));
                                if (record.size() >= 3) {
                                    recordDTO.setFielde3(record.get(2));
                                } else {
                                    recordDTO.setFielde3("");
                                }
                                recordDTOS.add(recordDTO);
                            }
                            if (!StringUtils.isEmpty(record.get(0)) && record.get(0).startsWith("试管名称")) {
                                SampleDTO sampleDTO = new SampleDTO();
                                sampleDTO.setHissampleCode(record.get(0));
                                sampleDTO.setSampleIndex(index);
                                sampleDTOs.add(sampleDTO);
                            }
                            if (!StringUtils.isEmpty(record.get(0)) && record.get(0).startsWith("全称")) {
                                analyteTitileIndexs.add(index);
                            }
                        }
                        // 将有效分析项数据整理到各自样本下
                        for (int i = 0; i < sampleDTOs.size(); i++) {
                            SampleDTO sampleDTO = sampleDTOs.get(i);
                            // 获取其分析项抬头行
                            int analyteTitleIndex = analyteTitileIndexs.get(i);
                            // 分析项的结束行不能大于下一个样本的坐标（如果不是最后一个样本），最后一个样本，小于所有总数据index即可
                            int analyteEndIndex = 0;
                            if (i != sampleDTOs.size()-1) {
                                // 非最后一个
                                analyteEndIndex = sampleDTOs.get(i + 1).getSampleIndex();
                            } else {
                                // 最后一个
                                analyteEndIndex = index;
                            }
                            // 从所有有效数据中获取样本分析项结果
                            for (CsvRecordDTO csvRecordDTO : recordDTOS) {
                                if (csvRecordDTO.getIndex() > analyteTitleIndex && csvRecordDTO.getIndex() < analyteEndIndex) {
                                    ResultDTO resultDTO = new ResultDTO();
                                    // 试管名称:0417-1，后边部分为分院样本编号
                                    resultDTO.setHissampleCode(sampleDTO.getHissampleCode().split("\\:")[1]);
                                    resultDTO.setAnalyte(csvRecordDTO.getFielde0());
                                    resultDTO.setResult(csvRecordDTO.getFielde3());
                                    resultDTO.setProductCode(TBNKCSV);
                                    resultDTO.setProductName(TBNKCSVNAME);
                                    results.add(resultDTO);
                                }
                            }
                        }
                        in.close();
                        is.close();
                        br.close();
                        parser.close();
                    }
                }
            }
            for (FTPFile file: files) {
                ftpClient.changeWorkingDirectory(dealChinesePath(tbnkOutput + "/" + file.getName()));
                ftpClient.makeDirectory(dealChinesePath(tbnkReaded + "/" + file.getName()));
                FTPFile[] files2 = ftpClient.listDirectories();
                for (FTPFile file2: files2) {
                    ftpClient.changeWorkingDirectory(dealChinesePath(tbnkOutput + "/" + file.getName() + "/" + file2.getName()));
                    ftpClient.makeDirectory(dealChinesePath(tbnkReaded + "/" + file.getName() + "/" + file2.getName()));
                    FTPFile[] files3 = ftpClient.listFiles();
                    for (FTPFile file3: files3) {
                        ftpClient.rename(dealChinesePath(tbnkOutput + "/" + file.getName() + "/" + file2.getName() + "/" + file3.getName()),
                            dealChinesePath(tbnkReaded + "/" + file.getName() + "/" + file2.getName() + "/" + file3.getName()));
                    }
                }
            }
        } catch (Exception e) {
            LOGGER.error("读取TBNK文件异常");
            e.printStackTrace();
        } finally {
            try {
                if (ftpClient != null) {
                    ftpClient.disconnect();
                }
                if (parser != null) {
                    // 关闭流
                    parser.close();
                }
                if (in != null) {
                    in.close();
                }
                if (is != null) {
                    is.close();
                }
                if (br != null) {
                    br.close();
                }
                if (os != null) {
                    os.close();
                }
            } catch (Exception e) {
                LOGGER.error("关闭TBNK文件流异常");
                e.printStackTrace();
            }
        }
    }

    /*
     * 读取当前电脑的取Tbnk文件，收集结果，并将原文件移至已读文件
     * */
    public void readTbnkFilesSix(String ip, String port, List<ResultDTO> results) {
        if (StringUtils.isEmpty(ip) || StringUtils.isEmpty(port)
                || StringUtils.isEmpty(tbnkPdfOutput) || StringUtils.isEmpty(tbnkPdfReaded)) {
            return;
        }
        // 匿名登录获取ftp连接
        FTPClient ftpClient = null;
        CSVParser parser = null;
        OutputStream os = null;
        InputStream in = null;
        InputStreamReader is = null;
        BufferedReader br = null;
        try {
            ftpClient = FtpUtils.getFtpClient(ip, Integer.valueOf(port), ANYUSER, "");
            if (ftpClient == null) {
                return;
            }
            // 文件层级为：/Output/20240417-TBNK_20240418_14_58 48_CSV/标本1_CSV/1.csv
            // 切换到未读文件夹
            ftpClient.changeWorkingDirectory(tbnkPdfOutput);
            FTPFile[] files = ftpClient.listDirectories();
            if (files == null || files.length == 0) {
                LOGGER.info("TBNK-6项未读文件夹：{}下暂无文件", tbnkPdfOutput);
                return;
            }
            for (FTPFile file: files) {
                LOGGER.info("读取2级文件夹：{}", file.getName());
                // 进入二级
                ftpClient.changeWorkingDirectory(dealChinesePath(tbnkPdfOutput + "/" + file.getName()));
                FTPFile[] files2 = ftpClient.listDirectories();
                for (FTPFile file2: files2) {
                    LOGGER.info("读取3级文件夹：{}", file2.getName());
                    // 进入三级
                    ftpClient.changeWorkingDirectory(dealChinesePath(tbnkPdfOutput + "/" + file.getName() + "/" + file2.getName()));
                    FTPFile[] files3 = ftpClient.listFiles();
                    for (FTPFile file3: files3) {
                        // 如果不是文件，则跳过
                        if (!file3.isFile() || (!file3.getName().endsWith("csv") && !file3.getName().endsWith("CSV"))) {
                            continue;
                        }
                        LOGGER.info("读取TBNK-6项文件：{}", file3.getName());
                        // 直接从路径读取csv文件
                        in = new BOMInputStream(ftpClient.retrieveFileStream(dealChinesePath(tbnkPdfOutput + "/" + file.getName()+ "/" + file2.getName() + "/" + file3.getName())));
                        is = new InputStreamReader(in);
                        br = new BufferedReader(is);
                        parser = new CSVParser(br, CSVFormat.DEFAULT);
                        ftpClient.getReply();
                        // 获取每个样本的数据收集区域信息
                        List<SampleDTO> sampleDTOs = new ArrayList<>();
                        // 所有全称，即分析项的抬头
                        List<Integer> analyteTitileIndexs = new ArrayList<>();
                        // 所有第一个单元格非空的数据，有效数据
                        List<CsvRecordDTO> recordDTOS = new ArrayList<>();
                        int index = 0;
                        for (CSVRecord record : parser) {
                            index++;
                            if (!StringUtils.isEmpty(record.get(0))) {
                                CsvRecordDTO recordDTO = new CsvRecordDTO();
                                recordDTO.setIndex(index);
                                recordDTO.setFielde0(record.get(0));
                                if (record.size() >= 3) {
                                    recordDTO.setFielde3(record.get(2));
                                } else {
                                    recordDTO.setFielde3("");
                                }
                                recordDTOS.add(recordDTO);
                            }
                            if (!StringUtils.isEmpty(record.get(0)) && record.get(0).startsWith("试管名称")) {
                                SampleDTO sampleDTO = new SampleDTO();
                                sampleDTO.setHissampleCode(record.get(0));
                                sampleDTO.setSampleIndex(index);
                                sampleDTOs.add(sampleDTO);
                            }
                            if (!StringUtils.isEmpty(record.get(0)) && record.get(0).startsWith("全称")) {
                                analyteTitileIndexs.add(index);
                            }
                        }
                        // 将有效分析项数据整理到各自样本下
                        for (int i = 0; i < sampleDTOs.size(); i++) {
                            SampleDTO sampleDTO = sampleDTOs.get(i);
                            // 获取其分析项抬头行
                            int analyteTitleIndex = analyteTitileIndexs.get(i);
                            // 分析项的结束行不能大于下一个样本的坐标（如果不是最后一个样本），最后一个样本，小于所有总数据index即可
                            int analyteEndIndex = 0;
                            if (i != sampleDTOs.size()-1) {
                                // 非最后一个
                                analyteEndIndex = sampleDTOs.get(i + 1).getSampleIndex();
                            } else {
                                // 最后一个
                                analyteEndIndex = index;
                            }
                            // 从所有有效数据中获取样本分析项结果
                            for (CsvRecordDTO csvRecordDTO : recordDTOS) {
                                if (csvRecordDTO.getIndex() > analyteTitleIndex && csvRecordDTO.getIndex() < analyteEndIndex) {
                                    ResultDTO resultDTO = new ResultDTO();
                                    // 试管名称:0417-1，后边部分为分院样本编号
                                    resultDTO.setHissampleCode(sampleDTO.getHissampleCode().split("\\:")[1]);
                                    resultDTO.setAnalyte(csvRecordDTO.getFielde0());
                                    resultDTO.setResult(csvRecordDTO.getFielde3());
                                    resultDTO.setProductCode(TBNKPDF);
                                    resultDTO.setProductName(TBNKPDFNAME);
                                    results.add(resultDTO);
                                }
                            }
                        }
                        in.close();
                        is.close();
                        br.close();
                        parser.close();
                    }
                }
            }
            for (FTPFile file: files) {
                ftpClient.changeWorkingDirectory(dealChinesePath(tbnkPdfOutput + "/" + file.getName()));
                ftpClient.makeDirectory(dealChinesePath(tbnkPdfReaded + "/" + file.getName()));
                FTPFile[] files2 = ftpClient.listDirectories();
                for (FTPFile file2: files2) {
                    ftpClient.changeWorkingDirectory(dealChinesePath(tbnkPdfOutput + "/" + file.getName() + "/" + file2.getName()));
                    ftpClient.makeDirectory(dealChinesePath(tbnkPdfReaded + "/" + file.getName() + "/" + file2.getName()));
                    FTPFile[] files3 = ftpClient.listFiles();
                    for (FTPFile file3: files3) {
                        ftpClient.rename(dealChinesePath(tbnkPdfOutput + "/" + file.getName() + "/" + file2.getName() + "/" + file3.getName()),
                                dealChinesePath(tbnkPdfReaded + "/" + file.getName() + "/" + file2.getName() + "/" + file3.getName()));
                    }
                }
            }
        } catch (Exception e) {
            LOGGER.error("读取TBNK-6项文件异常");
            e.printStackTrace();
        } finally {
            try {
                if (ftpClient != null) {
                    ftpClient.disconnect();
                }
                if (parser != null) {
                    // 关闭流
                    parser.close();
                }
                if (in != null) {
                    in.close();
                }
                if (is != null) {
                    is.close();
                }
                if (br != null) {
                    br.close();
                }
                if (os != null) {
                    os.close();
                }
            } catch (Exception e) {
                LOGGER.error("关闭TBNK-6项文件流异常");
                e.printStackTrace();
            }
        }
    }

    /*
     * 读取当前电脑的取Tbnk文件，收集结果，并将原文件移至已读文件
     * */
    public void readTbnkPdfFiles(String ip, String port, List<ResultDTO> results) {
        if (StringUtils.isEmpty(ip) || StringUtils.isEmpty(port)
            || StringUtils.isEmpty(tbnkPdfOutput) || StringUtils.isEmpty(tbnkPdfReaded)) {
            return;
        }
        // 匿名登录获取ftp连接
        FTPClient ftpClient = null;
        InputStream in = null;
        PDDocument load = null;
        try {
            ftpClient = FtpUtils.getFtpClient(ip, Integer.valueOf(port), ANYUSER, "");
            if (ftpClient == null) {
                return;
            }
            // 切换到未读文件夹
            ftpClient.changeWorkingDirectory(tbnkPdfOutput);
            FTPFile[] files = ftpClient.listFiles();
            if (files == null || files.length == 0) {
                LOGGER.info("TBNK-PDF未读文件夹：{}下暂无文件", tbnkPdfOutput);
                return;
            }
            for (FTPFile file: files) {
                LOGGER.info("读取TBNK-PDF文件：{}", file.getName());
                // 如果不是文件，则跳过
                if (!file.isFile() || (!file.getName().endsWith("pdf") && !file.getName().endsWith("PDF"))) {
                    continue;
                }
                String s = "";
                try {
                    in = ftpClient.retrieveFileStream(dealChinesePath(tbnkPdfOutput + "/" + file.getName()));
                    ftpClient.getReply();
                    load = PDDocument.load(in);
                    PDFTextStripper stripper = new PDFTextStripper();
                    s = stripper.getText(load);
                    in.close();
                    load.close();
                } catch (Exception e) {
                    LOGGER.info("读取PDF异常");
                    e.printStackTrace();
                }
                // LOGGER.info("读取数据：" + s);
                List<String> lines = Arrays.asList(s.split("\n"));
                String hissampleCode = "";
                String cd3plus = "";
                String cd3plusCd8plus = "";
                String cd3plusCd4plus = "";
                String cd16plusCd56plus = "";
                String cd19plus = "";
                String cd45plus = "";
                String fourOrEightRatio = "";
                for (int i = 0; i < lines.size(); i++) {
                    if(i == 1) {
                        if (!StringUtils.isEmpty(lines.get(i))) {
                            hissampleCode = lines.get(i).split(" ")[0];
                        }
                    }
                    if(i == 23) {
                        if (!StringUtils.isEmpty(lines.get(i))) {
                            cd3plus = lines.get(i).split(" ")[1];
                        }
                    }
                    if(i == 24) {
                        if (!StringUtils.isEmpty(lines.get(i))) {
                            cd3plusCd8plus = lines.get(i).split(" ")[1];
                        }
                    }
                    if(i == 25) {
                        if (!StringUtils.isEmpty(lines.get(i))) {
                            cd3plusCd4plus = lines.get(i).split(" ")[1];
                        }
                    }
                    if(i == 27) {
                        if (!StringUtils.isEmpty(lines.get(i))) {
                            cd16plusCd56plus = lines.get(i).split(" ")[1];
                        }
                    }
                    if(i == 28) {
                        if (!StringUtils.isEmpty(lines.get(i))) {
                            cd19plus = lines.get(i).split(" ")[1];
                        }
                    }
                    if(i == 29) {
                        if (!StringUtils.isEmpty(lines.get(i))) {
                            cd45plus = lines.get(i).split(" ")[1];
                        }
                    }
                    if(i == 30) {
                        if (!StringUtils.isEmpty(lines.get(i))) {
                            fourOrEightRatio = lines.get(i).split(" ")[2];
                        }
                    }
                }
                if (!StringUtils.isEmpty(hissampleCode)) {
                    if (!StringUtils.isEmpty(cd3plus)) {
                        ResultDTO resultDTO = new ResultDTO();
                        resultDTO.setHissampleCode(hissampleCode);
                        resultDTO.setAnalyte("CD3+");
                        resultDTO.setResult(cd3plus);
                        resultDTO.setProductCode(TBNKPDF);
                        resultDTO.setProductName(TBNKPDFNAME);
                        results.add(resultDTO);
                    }
                    if (!StringUtils.isEmpty(cd3plusCd8plus)) {
                        ResultDTO resultDTO = new ResultDTO();
                        resultDTO.setHissampleCode(hissampleCode);
                        resultDTO.setAnalyte("CD3+CD8+");
                        resultDTO.setResult(cd3plusCd8plus);
                        resultDTO.setProductCode(TBNKPDF);
                        resultDTO.setProductName(TBNKPDFNAME);
                        results.add(resultDTO);
                    }
                    if (!StringUtils.isEmpty(cd3plusCd4plus)) {
                        ResultDTO resultDTO = new ResultDTO();
                        resultDTO.setHissampleCode(hissampleCode);
                        resultDTO.setAnalyte("CD3+CD4+");
                        resultDTO.setResult(cd3plusCd4plus);
                        resultDTO.setProductCode(TBNKPDF);
                        resultDTO.setProductName(TBNKPDFNAME);
                        results.add(resultDTO);
                    }
                    if (!StringUtils.isEmpty(cd16plusCd56plus)) {
                        ResultDTO resultDTO = new ResultDTO();
                        resultDTO.setHissampleCode(hissampleCode);
                        resultDTO.setAnalyte("CD16+CD56+");
                        resultDTO.setResult(cd16plusCd56plus);
                        resultDTO.setProductCode(TBNKPDF);
                        resultDTO.setProductName(TBNKPDFNAME);
                        results.add(resultDTO);
                    }
                    if (!StringUtils.isEmpty(cd19plus)) {
                        ResultDTO resultDTO = new ResultDTO();
                        resultDTO.setHissampleCode(hissampleCode);
                        resultDTO.setAnalyte("CD19+");
                        resultDTO.setResult(cd19plus);
                        resultDTO.setProductCode(TBNKPDF);
                        resultDTO.setProductName(TBNKPDFNAME);
                        results.add(resultDTO);
                    }
                    if (!StringUtils.isEmpty(cd45plus)) {
                        ResultDTO resultDTO = new ResultDTO();
                        resultDTO.setHissampleCode(hissampleCode);
                        resultDTO.setAnalyte("CD45+");
                        resultDTO.setResult(cd45plus);
                        resultDTO.setProductCode(TBNKPDF);
                        resultDTO.setProductName(TBNKPDFNAME);
                        results.add(resultDTO);
                    }
                    if (!StringUtils.isEmpty(fourOrEightRatio)) {
                        ResultDTO resultDTO = new ResultDTO();
                        resultDTO.setHissampleCode(hissampleCode);
                        resultDTO.setAnalyte("4/8 Ratio");
                        resultDTO.setResult(fourOrEightRatio);
                        resultDTO.setProductCode(TBNKPDF);
                        resultDTO.setProductName(TBNKPDFNAME);
                        results.add(resultDTO);
                    }
                }
            }
            for (FTPFile file: files) {
                // 如果不是文件，则跳过
                if (!file.isFile() || (!file.getName().endsWith("pdf") && !file.getName().endsWith("PDF"))) {
                    continue;
                }
                ftpClient.rename(dealChinesePath(tbnkPdfOutput + "/" + file.getName()), dealChinesePath(tbnkPdfReaded + "/" + file.getName()));
            }
        } catch (Exception e) {
            LOGGER.error("读取TBNK-PDF文件异常");
            e.printStackTrace();
        } finally {
            try {
                if (ftpClient != null) {
                    ftpClient.disconnect();
                }
                if (in != null) {
                    in.close();
                }
                if (load != null) {
                    load.close();
                }
            } catch (Exception e) {
                LOGGER.error("关闭TBNK-PDF流异常");
                e.printStackTrace();
            }
        }
    }

    /*
    * 路径及文件名支持中文
    * */
    public static String dealChinesePath(String oriPath) {
        if (StringUtils.isEmpty(oriPath)) {
           return "";
        } else {
            try {
                return new String(oriPath.getBytes("UTF-8"), "ISO-8859-1");
            } catch (UnsupportedEncodingException e) {
                LOGGER.error("FTP路径解析异常");
                e.printStackTrace();
            }
        }
        return oriPath;
    }

}
